/*!
    \file    ws2812.h
    \brief   WS2812灯带SPI+DMA驱动头文件

    \version 2025-01-20, V1.0.0, WS2812驱动 for GD32C231C
*/

#ifndef WS2812_H
#define WS2812_H

#include "gd32c2x1.h"
#include "dmx512.h"
#include <stdint.h>
#include <stdbool.h>

/* WS2812协议时序定义 (基于SPI 6.4MHz时钟) */
#define WS2812_SPI_FREQ_HZ          6400000     /* SPI时钟频率 6.4MHz */
#define WS2812_BIT_0                0xC0        /* 逻辑0: 11000000 (0.25us高+0.75us低) */
#define WS2812_BIT_1                0xF8        /* 逻辑1: 11111000 (0.625us高+0.375us低) */
#define WS2812_RESET_BITS           50          /* 复位信号位数 (>50us低电平) */

/* WS2812硬件配置 */
#define WS2812_SPI                  SPI0        /* 使用SPI0 */
#define WS2812_SPI_CLK              RCU_SPI0    /* SPI0时钟 */
#define WS2812_GPIO_CLK             RCU_GPIOB   /* GPIO时钟 */
#define WS2812_GPIO_PORT            GPIOB       /* GPIO端口 */
#define WS2812_GPIO_PIN             GPIO_PIN_5  /* 数据引脚 PB5 */
#define WS2812_GPIO_AF              GPIO_AF_0   /* 复用功能 */

/* DMA配置 */
#define WS2812_DMA_CLK              RCU_DMA     /* DMA时钟 */
#define WS2812_DMA_CHANNEL          DMA_CH2     /* 使用DMA通道2 */
#define WS2812_DMA_REQUEST          DMA_REQUEST_SPI0_TX  /* SPI0发送DMA请求 */
#define WS2812_DMA_IRQ              DMA_Channel2_IRQn    /* DMA通道2中断 */

/* WS2812配置参数 */
#define WS2812_MAX_LEDS             64          /* 最大LED数量 */
#define WS2812_BYTES_PER_LED        3           /* 每个LED的字节数 (GRB) */
#define WS2812_BITS_PER_BYTE        8           /* 每字节位数 */
#define WS2812_SPI_BITS_PER_BIT     8           /* 每个WS2812位对应的SPI位数 */

/* 计算缓冲区大小 */
#define WS2812_BUFFER_SIZE(led_count) ((led_count) * WS2812_BYTES_PER_LED * WS2812_SPI_BITS_PER_BIT + WS2812_RESET_BITS)

/* RGB颜色结构体 (使用DMX512定义) */
/* rgb_color_t 已在dmx512.h中定义 */

/* WS2812状态枚举 */
typedef enum {
    WS2812_STATE_IDLE = 0,      /* 空闲状态 */
    WS2812_STATE_SENDING,       /* 发送数据中 */
    WS2812_STATE_COMPLETE       /* 发送完成 */
} ws2812_state_t;

/* WS2812控制结构体 */
typedef struct {
    uint8_t *spi_buffer;            /* SPI发送缓冲区 */
    uint16_t buffer_size;           /* 缓冲区大小 */
    uint16_t led_count;             /* LED数量 */
    rgb_color_t *led_colors;        /* LED颜色数组 */
    ws2812_state_t state;           /* 当前状态 */
    bool transmission_complete;     /* 传输完成标志 */
    bool auto_refresh;              /* 自动刷新标志 */
    uint32_t refresh_interval_ms;   /* 刷新间隔(毫秒) */
    uint32_t last_update_time;      /* 上次更新时间 */
} ws2812_handle_t;

/* 全局WS2812句柄 */
extern ws2812_handle_t g_ws2812;

/* WS2812驱动函数声明 */

/*!
    \brief      初始化WS2812驱动
    \param[in]  led_count: LED数量 (1-64)
    \param[out] none
    \retval     none
*/
void ws2812_init(uint16_t led_count);

/*!
    \brief      反初始化WS2812驱动
    \param[in]  none
    \param[out] none
    \retval     none
*/
void ws2812_deinit(void);

/*!
    \brief      设置单个LED颜色
    \param[in]  led_index: LED索引 (0-63)
    \param[in]  color: RGB颜色值
    \param[out] none
    \retval     none
*/
void ws2812_set_led_color(uint16_t led_index, rgb_color_t color);

/*!
    \brief      获取单个LED颜色
    \param[in]  led_index: LED索引 (0-63)
    \param[out] none
    \retval     RGB颜色值
*/
rgb_color_t ws2812_get_led_color(uint16_t led_index);

/*!
    \brief      设置多个LED颜色
    \param[in]  start_index: 起始LED索引
    \param[in]  colors: RGB颜色数组
    \param[in]  count: LED数量
    \param[out] none
    \retval     none
*/
void ws2812_set_led_colors(uint16_t start_index, rgb_color_t *colors, uint16_t count);

/*!
    \brief      发送WS2812数据
    \param[in]  none
    \param[out] none
    \retval     none
*/
void ws2812_send_data(void);

/*!
    \brief      检查WS2812传输是否完成
    \param[in]  none
    \param[out] none
    \retval     true: 传输完成, false: 传输中
*/
bool ws2812_is_transmission_complete(void);

/*!
    \brief      启用WS2812自动刷新
    \param[in]  interval_ms: 刷新间隔(毫秒)
    \param[out] none
    \retval     none
*/
void ws2812_enable_auto_refresh(uint32_t interval_ms);

/*!
    \brief      禁用WS2812自动刷新
    \param[in]  none
    \param[out] none
    \retval     none
*/
void ws2812_disable_auto_refresh(void);

/*!
    \brief      WS2812自动刷新处理函数 (在主循环中调用)
    \param[in]  none
    \param[out] none
    \retval     none
*/
void ws2812_auto_refresh_handler(void);

/*!
    \brief      WS2812 DMA中断处理函数
    \param[in]  none
    \param[out] none
    \retval     none
*/
void ws2812_dma_irq_handler(void);

/* WS2812灯带效果函数 */

/*!
    \brief      设置所有LED为单一颜色
    \param[in]  color: RGB颜色值
    \param[out] none
    \retval     none
*/
void ws2812_set_all_color(rgb_color_t color);

/*!
    \brief      彩虹效果
    \param[in]  offset: 颜色偏移量
    \param[out] none
    \retval     none
*/
void ws2812_rainbow_effect(uint8_t offset);

/*!
    \brief      呼吸灯效果
    \param[in]  color: 基础颜色
    \param[in]  brightness: 亮度 (0-255)
    \param[out] none
    \retval     none
*/
void ws2812_breathing_effect(rgb_color_t color, uint8_t brightness);

/*!
    \brief      流水灯效果
    \param[in]  color: 流水灯颜色
    \param[in]  position: 当前位置
    \param[in]  tail_length: 拖尾长度
    \param[out] none
    \retval     none
*/
void ws2812_flowing_effect(rgb_color_t color, uint16_t position, uint8_t tail_length);

/* 颜色工具函数 (复用DMX512实现) */

/*!
    \brief      HSV转RGB颜色
    \param[in]  hue: 色调 (0-359)
    \param[in]  saturation: 饱和度 (0-255)
    \param[in]  value: 明度 (0-255)
    \param[out] none
    \retval     RGB颜色值
*/
rgb_color_t ws2812_hsv_to_rgb(uint16_t hue, uint8_t saturation, uint8_t value);

/*!
    \brief      调整RGB颜色亮度
    \param[in]  color: 原始颜色
    \param[in]  brightness: 亮度系数 (0-255)
    \param[out] none
    \retval     调整后的RGB颜色值
*/
rgb_color_t ws2812_adjust_brightness(rgb_color_t color, uint8_t brightness);

/* 预定义颜色常量 */
#define WS2812_COLOR_BLACK      ((rgb_color_t){0, 0, 0})
#define WS2812_COLOR_WHITE      ((rgb_color_t){255, 255, 255})
#define WS2812_COLOR_RED        ((rgb_color_t){255, 0, 0})
#define WS2812_COLOR_GREEN      ((rgb_color_t){0, 255, 0})
#define WS2812_COLOR_BLUE       ((rgb_color_t){0, 0, 255})
#define WS2812_COLOR_YELLOW     ((rgb_color_t){255, 255, 0})
#define WS2812_COLOR_CYAN       ((rgb_color_t){0, 255, 255})
#define WS2812_COLOR_MAGENTA    ((rgb_color_t){255, 0, 255})
#define WS2812_COLOR_ORANGE     ((rgb_color_t){255, 165, 0})
#define WS2812_COLOR_PURPLE     ((rgb_color_t){128, 0, 128})

#endif /* WS2812_H */